<?php
/*

Version 0.1
SEMF - Web Desiging Framework for Sport Event Managment
Copyright (C) 2006, SEMF Developers

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

*/
include_once($semf_root.'page_designer/components/Component.php');

class GridComponent extends Component
{
	private static $WIDTH_PREFIX = "Width-Column";
	private static $HEIGHT_PREFIX = "Height-Row";
	
	/** properties with default values */
	public static function get_properties(){
		return array( 'Apearance' => array(
						'Rows'=> 2,
					 	'Columns'=> 2,
						'No_Overflow'=> 0,),
					   'DataBinding' => array(
						'Border-Color'=> -1,
						'Background-Color'=> -1),
						
					 );
	}
	
	/** This happens when container changes.. */
	public static function adjust_properties_with_container($parent_container, $properties)
	{
		// initally $key == NULL, 	
		$component = $parent_container->firstChild;
		
		/** here we need to think only apearance properties */
		$apearance_properties = $properties['Apearance'];
		$databinding_properties = $properties['DataBinding'];
		
		$parent_width = $parent_container-> getAttribute('width');
		$parent_height = $parent_container-> getAttribute('height');
		
		$rows = $properties['Apearance']['Rows'];
		$cols = $properties['Apearance']['Columns'];

		$row_sum = 0;
		$col_sum = 0;
		
		for( $i = 0; $i < $cols; $i ++ )
		{
			$column_id = GridComponent::$WIDTH_PREFIX.$i;
			$width = $properties['Apearance'][$column_id];
			if ( $width == NULL ) //devide things evenly..
			{
				// this should happen only when at the start..
				return NULL;
			}
			$col_sum += $width;
		}
		
		
		// this happens when parent had shrinked or widened a little bit..
		if ( $col_sum != 0 && 
				( ($col_sum - $parent_width) > 0.5 ||
				  ($col_sum - $parent_width) < -0.5) )
		{
			$ratio = $parent_width / $col_sum;
			//echo $ratio;
			$col_sum = 0;
		
			for( $i = 0; $i < $cols; $i ++ )
			{
				$column_id = GridComponent::$WIDTH_PREFIX.$i;
				$width = $properties['Apearance'][$column_id] * $ratio;
				if ( $i == $cols -1  ) //devide things evenly..
				{
					$width = $parent_width - $col_sum;
				}
				$properties['Apearance'][$column_id] = $width;
				$col_sum += $width;
			}
		}
		
		for( $i = 0; $i < $rows; $i ++ )
		{
			$row_id = GridComponent::$HEIGHT_PREFIX.$i;
			$height = $properties['Apearance'][$row_id];
			if ( $height == NULL ) //devide things evenly..
			{
				// this should happen only when at the start..
				return NULL;
			}
			$row_sum += $height;
		}
		
		if ( $row_sum != 0 && 
				( ($row_sum - $parent_height) > 0.5 ||
				  ($row_sum - $parent_height) < -0.5) )
		{
			$ratio = $parent_height / $row_sum;
			$row_sum = 0;
		
			for( $i = 0; $i < $rows; $i ++ )
			{
				$row_id = GridComponent::$HEIGHT_PREFIX.$i;
				$height = $properties['Apearance'][$row_id] * $ratio;
				if ( $i == $rows -1  ) //devide things evenly..
				{
					$height = $parent_height - $row_sum;
				}
				$properties['Apearance'][$row_id] = $height;
				$row_sum += $height;
			}
		}
		return $properties;
	}
	
	
	/** build properties dynamically if atmost one property is changed */
	public static function build_properties($parent_container, $properties, $property_group, $key, $value)
	{
		if($key == 'No_Overflow' || $key == 'Border-Color' || $key == 'Background-Color')
		{
			$properties[$property_group][$key] = $value;
			return $properties;
		}
		// initally $key == NULL, 	
		$component = $parent_container->firstChild;
		
		/** here we need to think only apearance properties */
		$apearance_properties = $properties['Apearance'];
		$databinding_properties = $properties['DataBinding'];
				
		$parent_width = $parent_container-> getAttribute('width');
		$parent_height = $parent_container-> getAttribute('height');
		
		$rows = $apearance_properties['Rows'];
		$cols = $apearance_properties['Columns'];
		
		$row_sum = 0;
		$col_sum = 0;
		/** Key == NULL 
		 *   this is assumed is at the start..
		 *   when user drag and drop an item
		 *   When open an existing file, so all the components have to be loaeded.
		 */
		if ( $key == NULL )
		{	
			for( $i = 0; $i < $cols; $i ++ )
			{
				$column_id = GridComponent::$WIDTH_PREFIX.$i;
				$width = $apearance_properties[$column_id];
				if ( $width == NULL ) //devide things evenly..
				{
					$width = ($parent_width - $col_sum)/($cols - $i );
					$apearance_properties[$column_id] = $width;
				}
				$col_sum += $width;
			}
			for( $i = 0; $i < $rows; $i ++ )
			{
				$row_id = GridComponent::$HEIGHT_PREFIX.$i;
				$height = $apearance_properties[$row_id];
				if ( $height == NULL ) //devide things evenly..
				{
					$height = ($parent_height - $row_sum)/($rows - $i );
					$apearance_properties[$row_id] = $height;
				}
				$row_sum += $height;
			}
		}
		else if ( $key == 'Columns')
		{
			$col_sum = 0;
			if ( $value < $cols ) // when new value is less
			{
				for( $i = 0; $i < $value; $i ++ )
				{
					$column_id = GridComponent::$WIDTH_PREFIX.$i;
					$width = $apearance_properties[$column_id];
					$col_sum +=  $width;
				}
				if ($col_sum != 0 )
				{
					$ratio = $parent_width / $col_sum;
					
					$col_sum = 0;
					
					for( $i = 0; $i < $value; $i ++ )
					{
						$column_id = GridComponent::$WIDTH_PREFIX.$i;
						$width = $apearance_properties[$column_id]* $ratio;
						if ( $i == value - 1) // correct the round off error
						{
							$width = $parent_width - $col_sum;
						}
						$col_sum +=  $width;
						$apearance_properties[$column_id] = $width;
					}
				}
			}
			else if ( $value > $cols ) // when new value is more
			{
				$new_cols_width = $parent_width / $value;
				
				$old_cols_width_total = $parent_width - $new_cols_width * ( $value- $cols );
				
				if( $parent_width != 0 )
				{
					$ratio = $old_cols_width_total / $parent_width;
					for( $i = 0; $i < $value; $i ++ )
					{
						$column_id = GridComponent::$WIDTH_PREFIX.$i;
						$width = $apearance_properties[$column_id]* $ratio;
						$col_sum +=  $width;
						$apearance_properties[$column_id] = $width;
					}
				}
				
				//update the $new_cols_width covering the round off error..
				$new_cols_width = ($parent_width - $col_sum ) / ($value- $cols );
				for ( $i = $cols; $i < $value ; $i ++ )
				{
					$column_id = GridComponent::$WIDTH_PREFIX.$i;
					$apearance_properties[$column_id] = $new_cols_width;
				}
				
			}
			$cols = $apearance_properties['Columns'] = $value;
		}

		else if ( $key == 'Rows')
		{
			$row_sum = 0;
			if ( $value < $rows ) // when new value is less
			{
				for( $i = 0; $i < $value; $i ++ )
				{
					$row_id = GridComponent::$HEIGHT_PREFIX.$i;
					$height = $apearance_properties[$row_id];
					$row_sum +=  $height;
				}
				if ($row_sum != 0 )
				{
					$ratio = $parent_height / $row_sum; // this should be greater than 1
					$row_sum = 0;
					
					for( $i = 0; $i < $value; $i ++ )
					{
						$row_id = GridComponent::$HEIGHT_PREFIX.$i;
						$height = $apearance_properties[$row_id]* $ratio;
						if ( $i == value - 1) // correct the round off error
						{
							$height = $parent_height - $row_sum;
						}
						$row_sum +=  $height;
						$apearance_properties[$row_id] = $height;
					}
				}
			}
			else if ( $value > $rows ) // when new value is more
			{
				$new_rows_height = $parent_height / $value;
				
				$old_rows_height_total = $parent_height - $new_rows_height * ( $value- $rows );
				
				if( $parent_height != 0 )
				{
					$ratio = $old_rows_height_total / $parent_height;
					for( $i = 0; $i < $value; $i ++ )
					{
						$row_id = GridComponent::$HEIGHT_PREFIX.$i;
						$height = $apearance_properties[$row_id]* $ratio;
						$row_sum +=  $height;
						$apearance_properties[$row_id] = $height;
					}
				}
				
				//update the $new_cols_width covering the round off error..
				$new_rows_height = ($parent_height - $row_sum ) / ($value- $rows );
				for ( $i = $rows; $i < $value ; $i ++ )
				{
					$row_id = GridComponent::$HEIGHT_PREFIX.$i;
					$apearance_properties[$row_id] = $new_rows_height;
				}
				
			}
			$rows = $apearance_properties['Rows'] = $value;
		}
		else //change in widths or height
		{
			//change of a width
			$change_width = false;
			$column_sum = 0;
			$ratio = 0;
			for( $i = 0; $i < $cols; $i ++ ) //last column is not changed..
			{
				$column_id = GridComponent::$WIDTH_PREFIX.$i;
				if ( $column_id == $key ) // this is the value to change
				{
					if($i == $cols -1)
					{
						break; //just quit..
					}
					$old_value = $apearance_properties[$column_id];
					if( $column_sum + $value > $parent_width ) // too much width
					{
						break;
					}
					$ratio = ($parent_width - ( $column_sum + $value ) )/
					           ($parent_width - ( $column_sum + $old_value ) );
					$change_width = true;
					$apearance_properties[$column_id] = $value;
				}
				else if( $change_width == true )
				{
					if( $i == $cols -1 ) //avoid the round off error..
					{
						$apearance_properties[$column_id] = $parent_width - $column_sum;
					}
					else
					{
					 	$apearance_properties[$column_id] *= $ratio;
					}
				}
				
				$column_sum += $apearance_properties[$column_id];
			}
			
			//change of a height
			$change_height = false;
			$row_sum = 0;
			$ratio = 0;
			for( $i = 0; $i < $rows && !$change_width; $i ++ )
			{
				$row_id = GridComponent::$HEIGHT_PREFIX.$i;
				if ( $row_id == $key ) // this is the value to change
				{
					if($i == $rows -1)
					{
						break; //just quit..
					}
					$old_value = $apearance_properties[$row_id];
					if( $row_sum + $value > $parent_height ) // too much height
					{
						break;
					}
					$ratio = ($parent_height - ( $row_sum + $value ) )/
					           ($parent_height - ( $row_sum + $old_value ) );
					$change_height = true;
					$apearance_properties[$row_id] = $value;
				}
				else if( $change_height == true )
				{
					if( $i == $rows -1 ) //avoid the round off error..
					{
						$apearance_properties[$row_id] = $parent_height - $row_sum;
					}
					else
					{
					 	$apearance_properties[$row_id] *= $ratio;
					}
				}
				
				$row_sum += $apearance_properties[$row_id];
			}
			
			
		}
		

		$new_apearance_properties = array(
									'Rows'=> $apearance_properties['Rows'],
					 				'Columns'=> $apearance_properties['Columns'],
									'No_Overflow'=> $apearance_properties['No_Overflow']);
					 
		
		for( $i = 0; $i < $cols; $i ++ )
		{
			$column_id = GridComponent::$WIDTH_PREFIX.$i;
			$temp = array("$column_id"=> $apearance_properties[$column_id]);
			
			$new_apearance_properties = array_merge ($new_apearance_properties, $temp);
		}
				
		for( $i = 0; $i < $rows; $i ++ )
		{
			$row_id = GridComponent::$HEIGHT_PREFIX.$i;
			$temp = array("$row_id"=> $apearance_properties[$row_id]);
			
			$new_apearance_properties = array_merge ($new_apearance_properties, $temp);
		}
		
		$new_array['Apearance'] = $new_apearance_properties;
		$new_array['DataBinding'] = array(
									'Border-Color'=> $databinding_properties['Border-Color'],
									'Background-Color'=> $databinding_properties['Background-Color']);
		
		/** now just copy the rest tabs to the new array */
		$property_tab_keys = array_keys($properties);
		foreach( $property_tab_keys as $property_tab_key )
		{
			if( $property_tab_key == 'Apearance' )
			{
				continue;
			}
			$new_array[$property_tab_key] = $properties[$property_tab_key];
		}
		
		return $new_array;
		
	}
	
	/** containers */
	public static function build_containers( $parent_container, $properties)
	{
		$component = $parent_container->firstChild;
		
		/** here we need to think only apearance properties */
		$apearance_properties = $properties['Apearance'];
		
		$cols = $rows = 0;
		
		$rows = $apearance_properties['Rows'];
		$cols = $apearance_properties['Columns'];
		$border_color = $properties['DataBinding']['Border-Color'];
		
		$border = strpos($border_color , '#');
		
		$row_height = array();
		$col_width = array();
		
		for( $i = 0; $i < $rows; $i ++ )
		{
			$index = GridComponent::$HEIGHT_PREFIX.$i;
			$row_height[$i] =  $apearance_properties[$index];
		}
		
		for( $i = 0; $i < $cols; $i ++ )
		{
			$index = GridComponent::$WIDTH_PREFIX.$i;
			$col_width[$i] = $apearance_properties[$index];
		}
		
		$component_id = $component-> getAttribute('id');
		
		$parent_x = $parent_container-> getAttribute('x');
		$parent_y = $parent_container-> getAttribute('y');
		$parent_width = $parent_container-> getAttribute('width');
		$parent_height = $parent_container-> getAttribute('height');
		
		$container_id = NULL;
		$containers = array();
		$temp = NULL;
		
		$row_sum = array();
		$col_sum = 0;
		
		$x = $y = $width = $height = 0;
		
		
		for( $i = 0; $i < $rows; $i ++ )
		{
			$row_sum[$i] = 0;
			for( $j = 0; $j < $cols; $j ++ )
			{				
				$container_id = "_${i}${j}${component_id}";
				
				if($border !== false)
				{
					if($col_width[$j] > 4 && $row_height[$i] > 4)
					{
						$x = $row_sum[$i] + 2;
						$y = $col_sum + 2;
						$width = $col_width[$j] - 4;
						$height = $row_height[$i] -4;
					}
				}
				else
				{
					$x = $row_sum[$i];
					$y = $col_sum;
					$width = $col_width[$j];
					$height = $row_height[$i];
				}
				$row_sum[$i] +=  $col_width[$j];
					
				$temp = array( $container_id => 
								array (	'x' => $x,
										'y' => $y,
										'width' => $width,
										'height' => $height
										)
								);
				$containers = array_merge ($containers, $temp);
			}
			$col_sum += $row_height[$i];
		}
		return $containers;
	}
	
	public static function delcare_container_lines($properties)
	{
		$apearance_properties = $properties['Apearance'];
		
		$cols = $rows = 0;
		
		$rows = $apearance_properties['Rows'];
		$cols = $apearance_properties['Columns'];
		
		$parent_x = $parent_container-> getAttribute('x');
		$parent_y = $parent_container-> getAttribute('y');
		$parent_width = $parent_container-> getAttribute('width');
		$parent_height = $parent_container-> getAttribute('height');
		
		$count = 0;
		$lines_array = array();
		
		$last_line_x = 0;
		$last_line_y = 0;
		
		for( $i = 0; $i < $cols-1; $i ++ ) //except for the last one..
		{
			$index = GridComponent::$WIDTH_PREFIX.$i;
			$lines_array[$count] = array('target' => $index,
											'relative_to' => $last_line_x + $parent_x ,
											'dir' => 'ver',
											'start'=> $parent_y,
											'end' => $parent_y + $parent_height);
			$width =  $apearance_properties[$index];
			$last_line_x += $width;
			$count ++;
		}
		
		for( $i = 0; $i < $rows-1; $i ++ )
		{
			$index = GridComponent::$HEIGHT_PREFIX.$i;
			$lines_array[$count] = array('target' => $index,
											'relative_to' => $last_line_y + $parent_y ,
											'dir' => 'hor',
											'start'=> $parent_x,
											'end' => $parent_x + $parent_width);
			$height =  $apearance_properties[$index];
			$last_line_y += $height;
			$count ++;
		}
		
		return $lines_array;
	}
	
	public static function get_property_info($component_id, $properties)
	{
		return array(
					 'Background-Color'=> array(
							'attri' => 'style.backgroundColor', 
							'databind' => "inner_".$component_id));
	}
}
?>